"""
工作流编排器 - 智能更新流程编排
"""

import time
import logging
from typing import Dict, Any, Optional

from .types import (
    WorkflowResult, StepContext, StepResult, StepType, 
    ActionType, ContainerConfig
)
from .image_verification_service import ImageVerificationService
from .container_management_service import ContainerManagementService
from .pattern_matching_service import PatternMatchingService
from ..image_update_status import ImageUpdateStatusManager


logger = logging.getLogger(__name__)


class WorkflowOrchestrator:
    """智能更新流程编排器"""
    
    def __init__(self, 
                 verification_service: ImageVerificationService = None,
                 container_service: ContainerManagementService = None,
                 pattern_service: PatternMatchingService = None,
                 status_manager: ImageUpdateStatusManager = None):
        self.logger = logging.getLogger(self.__class__.__name__)
        
        # 依赖注入
        self.verification_service = verification_service or ImageVerificationService()
        self.container_service = container_service or ContainerManagementService()
        self.pattern_service = pattern_service or PatternMatchingService()
        self.status_manager = status_manager
        
        # 步骤定义
        self.steps = [
            StepType.LWX_PARSE,
            StepType.IMAGE_VERIFY,
            StepType.CONDITIONAL_PULL,
            StepType.CONTAINER_REBUILD
        ]
    
    def execute_intelligent_update(self, school_name: str, base_image: str) -> WorkflowResult:
        """
        执行智能更新流程
        
        Args:
            school_name: 学校名称
            base_image: 基础镜像版本
            
        Returns:
            WorkflowResult: 工作流执行结果
        """
        start_time = time.time()
        steps_completed = 0
        total_steps = len(self.steps)
        execution_details = {}
        
        try:
            self.logger.info(f"开始智能更新流程: 学校={school_name}, 镜像={base_image}")
            
            # 步骤1: LWX平台数据解析（构建上下文）
            context = self._build_context(school_name, base_image)
            if not context:
                return WorkflowResult(
                    success=False,
                    action_taken=ActionType.NONE,
                    message="构建执行上下文失败",
                    steps_completed=0,
                    total_steps=total_steps,
                    details={"error": "Failed to build execution context"},
                    execution_time=time.time() - start_time
                )
            
            step1_result = StepResult(
                step_type=StepType.LWX_PARSE,
                success=True,
                message="LWX平台数据解析完成",
                data={
                    "school_name": context.school_name,
                    "base_image": context.base_image,
                    "full_image_url": context.full_image_url,
                    "compose_file": context.compose_file,
                    "container_name": context.container_name
                }
            )
            steps_completed += 1
            execution_details["step1"] = step1_result.__dict__
            self._notify_progress(steps_completed, total_steps, "LWX平台数据解析完成")
            
            # 步骤2: 智能镜像版本校验
            step2_result = self._execute_verification_step(context)
            steps_completed += 1
            execution_details["step2"] = step2_result.__dict__
            self._notify_progress(steps_completed, total_steps, step2_result.message)
            
            if not step2_result.success:
                return self._build_failure_result(
                    ActionType.NONE, step2_result.error, 
                    steps_completed, total_steps, execution_details, start_time
                )
            
            # 更新上下文中的校验结果
            context.verification_result = step2_result.data.get('verification_result')
            
            # 根据校验结果决定是否需要后续步骤
            action_type = context.verification_result.action_type
            
            if action_type == ActionType.NONE:
                # 无需操作，直接返回成功
                return WorkflowResult(
                    success=True,
                    action_taken=ActionType.NONE,
                    message="镜像版本正确且容器正常运行，无需更新",
                    steps_completed=steps_completed,
                    total_steps=total_steps,
                    details=execution_details,
                    execution_time=time.time() - start_time
                )
            
            # 步骤3: 条件性镜像拉取
            step3_result = self._execute_conditional_pull_step(context)
            execution_details["step3"] = step3_result.__dict__
            
            if not step3_result.skipped:
                steps_completed += 1
                self._notify_progress(steps_completed, total_steps, step3_result.message)
                
                if not step3_result.success:
                    return self._build_failure_result(
                        action_type, step3_result.error,
                        steps_completed, total_steps, execution_details, start_time
                    )
            
            # 步骤4: 智能容器重建
            step4_result = self._execute_container_rebuild_step(context)
            steps_completed += 1
            execution_details["step4"] = step4_result.__dict__
            self._notify_progress(steps_completed, total_steps, step4_result.message)
            
            if not step4_result.success:
                return self._build_failure_result(
                    action_type, step4_result.error,
                    steps_completed, total_steps, execution_details, start_time
                )
            
            # 成功完成所有步骤
            execution_time = time.time() - start_time
            success_message = f"智能更新完成，执行了 {action_type.value} 操作"
            
            self.logger.info(f"智能更新流程完成: {success_message}, 耗时: {execution_time:.2f}秒")
            
            return WorkflowResult(
                success=True,
                action_taken=action_type,
                message=success_message,
                steps_completed=steps_completed,
                total_steps=total_steps,
                details=execution_details,
                execution_time=execution_time
            )
            
        except Exception as e:
            self.logger.error(f"智能更新流程执行失败: {e}")
            return WorkflowResult(
                success=False,
                action_taken=ActionType.NONE,
                message=f"执行流程时发生异常: {str(e)}",
                steps_completed=steps_completed,
                total_steps=total_steps,
                details=execution_details,
                execution_time=time.time() - start_time
            )
    
    def execute_single_step(self, step_type: StepType, context: StepContext) -> StepResult:
        """
        执行单个步骤（用于手动模式）
        
        Args:
            step_type: 步骤类型
            context: 执行上下文
            
        Returns:
            StepResult: 步骤执行结果
        """
        try:
            if step_type == StepType.LWX_PARSE:
                return StepResult(
                    step_type=step_type,
                    success=True,
                    message="LWX平台数据解析完成",
                    data=context.__dict__
                )
            elif step_type == StepType.IMAGE_VERIFY:
                return self._execute_verification_step(context)
            elif step_type == StepType.CONDITIONAL_PULL:
                return self._execute_conditional_pull_step(context)
            elif step_type == StepType.CONTAINER_REBUILD:
                return self._execute_container_rebuild_step(context)
            else:
                return StepResult(
                    step_type=step_type,
                    success=False,
                    message=f"未知的步骤类型: {step_type}",
                    error=f"Unknown step type: {step_type}"
                )
                
        except Exception as e:
            self.logger.error(f"执行步骤 {step_type} 失败: {e}")
            return StepResult(
                step_type=step_type,
                success=False,
                message=f"步骤执行失败: {str(e)}",
                error=str(e)
            )
    
    def _build_context(self, school_name: str, base_image: str) -> Optional[StepContext]:
        """构建执行上下文"""
        try:
            # 构建完整镜像URL
            full_image_url = self.pattern_service.build_full_image_url(base_image)
            
            # 选择compose文件
            compose_file = self.pattern_service.select_compose_file(base_image)
            
            # 提取容器名称
            container_name = self.pattern_service.extract_container_name_from_compose(compose_file)
            if not container_name:
                # 如果无法从compose文件提取，使用默认命名规则
                image_base_name = base_image.split(':')[0].split('/')[-1]
                container_name = f"{image_base_name}-service"
            
            return StepContext(
                school_name=school_name,
                base_image=base_image,
                full_image_url=full_image_url,
                container_name=container_name,
                compose_file=compose_file
            )
            
        except Exception as e:
            self.logger.error(f"构建执行上下文失败: {e}")
            return None
    
    def _execute_verification_step(self, context: StepContext) -> StepResult:
        """执行镜像版本校验步骤"""
        try:
            verification_result = self.verification_service.verify_image_status(
                context.full_image_url, 
                context.container_name
            )
            
            return StepResult(
                step_type=StepType.IMAGE_VERIFY,
                success=True,
                message=f"镜像版本校验完成: {verification_result.reason}",
                data={
                    "verification_result": verification_result,
                    "action_type": verification_result.action_type.value,
                    "needs_action": verification_result.needs_action
                }
            )
            
        except Exception as e:
            return StepResult(
                step_type=StepType.IMAGE_VERIFY,
                success=False,
                message=f"镜像版本校验失败: {str(e)}",
                error=str(e)
            )
    
    def _execute_conditional_pull_step(self, context: StepContext) -> StepResult:
        """执行条件性镜像拉取步骤"""
        try:
            if not context.verification_result:
                return StepResult(
                    step_type=StepType.CONDITIONAL_PULL,
                    success=False,
                    message="缺少校验结果，无法执行条件性拉取",
                    error="Missing verification result"
                )
            
            action_type = context.verification_result.action_type
            
            # 只有在需要更新或重建时才拉取镜像
            if action_type in [ActionType.UPDATE, ActionType.REBUILD]:
                # 这里可以添加镜像拉取逻辑，目前由container_service处理
                return StepResult(
                    step_type=StepType.CONDITIONAL_PULL,
                    success=True,
                    message=f"准备拉取镜像用于 {action_type.value} 操作",
                    data={"action_type": action_type.value}
                )
            else:
                return StepResult(
                    step_type=StepType.CONDITIONAL_PULL,
                    success=True,
                    message=f"无需拉取镜像，将执行 {action_type.value} 操作",
                    skipped=True,
                    data={"action_type": action_type.value}
                )
                
        except Exception as e:
            return StepResult(
                step_type=StepType.CONDITIONAL_PULL,
                success=False,
                message=f"条件性镜像拉取步骤失败: {str(e)}",
                error=str(e)
            )
    
    def _execute_container_rebuild_step(self, context: StepContext) -> StepResult:
        """执行智能容器重建步骤"""
        try:
            if not context.verification_result:
                return StepResult(
                    step_type=StepType.CONTAINER_REBUILD,
                    success=False,
                    message="缺少校验结果，无法执行容器操作",
                    error="Missing verification result"
                )
            
            action_type = context.verification_result.action_type
            
            # 构建容器配置
            container_config = ContainerConfig(
                image_url=context.full_image_url,
                container_name=context.container_name,
                school_name=context.school_name,
                ports={"8080": "8080"},  # 默认端口映射
                environment={
                    "SCHOOL_NAME": context.school_name,
                    "IMAGE_VERSION": context.base_image
                }
            )
            
            # 执行相应的容器操作
            operation_result = self.container_service.execute_action(
                action_type, 
                context.container_name, 
                container_config
            )
            
            if operation_result.success:
                return StepResult(
                    step_type=StepType.CONTAINER_REBUILD,
                    success=True,
                    message=f"容器操作完成: {operation_result.message}",
                    data={
                        "action_type": action_type.value,
                        "container_name": context.container_name,
                        "operation_details": operation_result.details
                    }
                )
            else:
                return StepResult(
                    step_type=StepType.CONTAINER_REBUILD,
                    success=False,
                    message=f"容器操作失败: {operation_result.message}",
                    error=operation_result.error,
                    data={"action_type": action_type.value}
                )
                
        except Exception as e:
            return StepResult(
                step_type=StepType.CONTAINER_REBUILD,
                success=False,
                message=f"智能容器重建失败: {str(e)}",
                error=str(e)
            )
    
    def _build_failure_result(self, action_type: ActionType, error: str, 
                            steps_completed: int, total_steps: int,
                            details: Dict[str, Any], start_time: float) -> WorkflowResult:
        """构建失败结果"""
        return WorkflowResult(
            success=False,
            action_taken=action_type,
            message=f"智能更新流程失败: {error}",
            steps_completed=steps_completed,
            total_steps=total_steps,
            details=details,
            execution_time=time.time() - start_time
        )
    
    def _notify_progress(self, current_step: int, total_steps: int, message: str):
        """通知进度更新"""
        if self.status_manager:
            progress = int((current_step / total_steps) * 100)
            self.status_manager.update_progress(progress, message)
        
        self.logger.info(f"步骤进度: {current_step}/{total_steps} - {message}")